package net.kuratkoo.jidelnicekvut;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import java.util.Calendar;

public class Canteen {

    private static final String TAG = "JidelnicekVUT|Canteen";
    public String name;
    public Integer canteenId;
    public String address;
    public String guid;
    public Boolean valid;
    public Boolean star;
    public CanteenHourSet canteenHourSet;
    private Context context;

    public Canteen(Context context) {
        this.context = context;
        this.valid = false;
        this.star = false;
        this.canteenHourSet = new CanteenHourSet(context);
    }

    public Canteen getByCanteenId(Integer canteenId) {
        DatabaseAdapter db = new DatabaseAdapter(this.context);
        Cursor c = db.getDb().rawQuery("SELECT * FROM canteen c LEFT JOIN canteen_star cs ON cs.canteen_id = c._id WHERE _id = ?", new String[]{canteenId.toString()});
        if (c.getCount() == 1) {
            c.moveToFirst();
            this.canteenId = canteenId;
            this.name = c.getString(c.getColumnIndex("name"));
            this.address = c.getString(c.getColumnIndex("address"));
            this.guid = c.getString(c.getColumnIndex("guid"));
            if (c.getInt(c.getColumnIndex("valid")) == 1) {
                this.valid = true;
            }
            if (c.getInt(c.getColumnIndex("canteen_id")) != 0) {
                this.star = true;
            }
            this.canteenHourSet.getByCanteenId(canteenId);
        }
        c.close();
        db.close();
        return this;
    }

    public void save() {
        DatabaseAdapter db = new DatabaseAdapter(this.context);
        ContentValues values = new ContentValues();
        values.put("name", this.name);
        values.put("_id", this.canteenId);
        values.put("address", this.address);
        values.put("guid", this.guid);
        if (this.valid) {
            values.put("valid", 1);
        } else {
            values.put("valid", 0);
        }
        db.getDb().insertOrThrow("canteen", null, values);
        db.close();
    }

    public String getFormatedOpeningHours() {
        String open = new String();
        Integer lastDay = 0;
        for (CanteenHour ch : this.canteenHourSet) {
            if (lastDay != ch.day) {
                switch (ch.day) {
                    case 1:
                        open = open.concat(this.context.getText(R.string.monday_thursday) + ":\t\t");
                        break;
                    case 5:
                        open = open.concat(this.context.getText(R.string.friday) + ":\t\t\t\t");
                        break;
                    case 6:
                        open = open.concat(this.context.getText(R.string.saturday_sunday) + ":\t");
                        break;
                    default:
                        break;
                }
            } else {
                open = open.concat("\t\t\t\t\t");
            }
            open = open.concat(ch.from.getHours() + ":" + Strings.prepandZero(ch.from.getMinutes()));
            open = open.concat(" - ");
            open = open.concat(ch.to.getHours() + ":" + Strings.prepandZero(ch.to.getMinutes()));
            open = open.concat("\n");
            lastDay = ch.day;
        }
        return open.trim();
    }

    public String getFormatedOpeningInfo() {
        String info = new String();

        Calendar c = Calendar.getInstance();
        Integer day = c.get(Calendar.DAY_OF_WEEK);
        Integer hours = c.get(Calendar.HOUR_OF_DAY);
        Integer minutes = c.get(Calendar.MINUTE);
        String[] czechDay = new String[]{"v pondělí", "v úterý", "ve středu", "ve čtvrtek", "v pátek", "v sobotu", "v neděli"};

        if (day == 2 || day == 3 || day == 4 || day == 5) { // Po-Ct
            day = 1;
        } else if (day == 6) { // Pa
            day = 5;
        } else if (day == 7 || day == 1) { // So-Ne
            day = 6;
        }

        if (this.isOpen()) {
            for (CanteenHour ch : this.canteenHourSet) {
                if (ch.day == day) {
                    if (ch.from.getHours() < hours && ch.to.getHours() > hours) {
                        // Time is between hours
                        return this.context.getText(R.string.closes_at).toString() + " " + ch.to.getHours() + ":" + Strings.prepandZero(ch.to.getMinutes());
                    } else if (ch.from.getHours() == hours && ch.from.getMinutes() <= minutes) {
                        return this.context.getText(R.string.closes_at).toString() + " " + ch.to.getHours() + ":" + Strings.prepandZero(ch.to.getMinutes());
                    } else if (ch.to.getHours() == hours && ch.to.getMinutes() >= minutes) {
                        return this.context.getText(R.string.closes_at).toString() + " " + ch.to.getHours() + ":" + Strings.prepandZero(ch.to.getMinutes());
                    }
                }
            }
        }

        // Today ?
        for (CanteenHour ch : this.canteenHourSet) {
            if (ch.day == day
                    && ch.from.getHours() > hours
                    || (ch.from.getHours() == hours && ch.from.getMinutes() > minutes)) {
                return this.context.getText(R.string.open_today_at).toString() + " " + ch.from.getHours() + ":" + Strings.prepandZero(ch.from.getMinutes());
            }
        }

        // Tomorrow ?
        day = c.get(Calendar.DAY_OF_WEEK);
        switch (day) {
            case 1:
                day = 1;
                break; // Sunday
            case 2:
                day = 1;
                break; // Monday
            case 3:
                day = 1;
                break;
            case 4:
                day = 1;
                break;
            case 5:
                day = 5; // Thursday
                break;
            case 6:
                day = 6;
                break; // Friday
            case 7:
                day = 6;
                break; // Saturday
        }
        for (CanteenHour ch : this.canteenHourSet) {
            if (ch.day == day) {
                return this.context.getText(R.string.open_tommorow_at).toString() + " " + ch.from.getHours() + ":" + Strings.prepandZero(ch.from.getMinutes());
            }
        }

        // Just next interval
        for (CanteenHour ch : this.canteenHourSet) {
            return this.context.getText(R.string.opens).toString() + " " + czechDay[ch.day - 1] + " v " + ch.from.getHours() + ":" + Strings.prepandZero(ch.from.getMinutes());
        }

        return info;
    }

    public Boolean isOpen() {
        Calendar c = Calendar.getInstance();
        Integer day = c.get(Calendar.DAY_OF_WEEK);
        Integer hours = c.get(Calendar.HOUR_OF_DAY);
        Integer minutes = c.get(Calendar.MINUTE);
        Boolean open = false;

        if (day == 2 || day == 3 || day == 4 || day == 5) { // Po-Ct
            day = 1;
        } else if (day == 6) { // Pa
            day = 5;
        } else if (day == 7 || day == 1) { // So-Ne
            day = 6;
        }

        for (CanteenHour ch : this.canteenHourSet) {
            if (ch.day == day) {
                if (ch.from.getHours() < hours && ch.to.getHours() > hours) {
                    open = true;
                    break;
                } else if (ch.from.getHours() == hours && ch.from.getMinutes() <= minutes) {
                    open = true;
                    break;
                } else if (ch.to.getHours() == hours && ch.to.getMinutes() >= minutes) {
                    open = true;
                    break;
                }
            }
        }
        return open;
    }

    public Boolean isCloseToClosing() {
        if (this.isOpen()) {
            Calendar c = Calendar.getInstance();
            Integer day = c.get(Calendar.DAY_OF_WEEK);
            Integer hours = c.get(Calendar.HOUR_OF_DAY);
            Integer minutes = c.get(Calendar.MINUTE);
            Integer minutesToClose = 0;

            if (day == 2 || day == 3 || day == 4 || day == 5) { // Po-Ct
                day = 1;
            } else if (day == 6) { // Pa
                day = 5;
            } else if (day == 7 || day == 1) { // So-Ne
                day = 6;
            }

            for (CanteenHour ch : this.canteenHourSet) {
                if (ch.day == day) {
                    if (ch.from.getHours() < hours && ch.to.getHours() > hours) {
                        minutesToClose = (ch.to.getHours() - hours) * 60 - minutes + ch.to.getMinutes();
                        break;
                    } else if (ch.from.getHours() == hours && ch.from.getMinutes() <= minutes) {
                        minutesToClose = (ch.to.getHours() - hours) * 60 - minutes + ch.to.getMinutes();
                        break;
                    } else if (ch.to.getHours() == hours && ch.to.getMinutes() >= minutes) {
                        minutesToClose = (ch.to.getHours() - hours) * 60 - minutes + ch.to.getMinutes();
                        break;
                    }
                }
            }

            if (minutesToClose > 0 && minutesToClose < 30) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public Canteen toggleStar() {
        DatabaseAdapter db = new DatabaseAdapter(this.context);
        if (this.star) {
            this.star = false;
            db.getDb().delete("canteen_star", "canteen_id = ?", new String[]{this.canteenId.toString()});
        } else {
            this.star = true;
            ContentValues values = new ContentValues();
            values.put("canteen_id", this.canteenId);
            db.getDb().insert("canteen_star", null, values);
        }
        db.close();
        return this;
    }

    public Boolean isShowable() {
        if (Preferences.getBoolean(context, "showOnlyFav", false) && Preferences.getBoolean(context, "showOnlyOpen", false)) {
            return this.star && this.isOpen();
        } else if (Preferences.getBoolean(context, "showOnlyFav", false)) {
            return this.star;
        } else if (Preferences.getBoolean(context, "showOnlyOpen", false)) {
            return this.isOpen();
        } else {
            return true;
        }
    }
}
